/**
 * DiceModel repraesentiert die interne Darstellung eines Wurfels.
 *
 * @author Michael Hansen
 * @author Lukas Thuernagel
 * @author Soeren Warszus
 */

package risk.dice;

import java.util.*;


public class DiceModel 
{
    /**
     * Enthaelt registrierte DiceViews.
     */
    private ArrayList views = null; 
    
    /**
     * Speichert fuer jeden sichtbaren View den letzten Wuerfelwurf.
     */
    private int[] pips;
    
    /**
     * Der Konstruktur erstellt eine neue Arraylist.
     * Diese wird effektiv nur benoetigt wenn dem Model mehrere Views
     * zugeordnet werden.
     */
    public DiceModel () 
    {
        views = new ArrayList();
    }

    
    /**
     * Die Methode registriert einen View beim Model. 
     *
     * @param view Der zu registrierende DiceView.
     */
    public void registerView (DiceView view) 
    {
        if (view == null) {
            throw new IllegalArgumentException("Cannot add null object to DiceModel");
        }
        
        views.add(view);
    }
    
    
    /**
     * Ermoeglicht das unregistrieren eines Views.
     *
     * @param view Der zu "loeschende" DiceView.
     */
    public boolean unregisterView(DiceView view)
    {
        int index = 0;
        boolean found = false;
        // Alle registrierten Views durchlaufen
        while (index < views.size()) {
            // und bei gesuchtem View stoppen.
            if (views.get(index) == view) {
                found = true;
                break;
            }
            index++;
        }
        
        // Wenn der gesuchte View gefunden wurde, nehmen wir ihn aus der 
        // ArrayList heraus.
        if (found) {
            views.remove(index);
            return true;
        } 
            
        return false;
    }
    
    
    /**
     * Gibt die zuletzt gewuerfelte Augenzahl des Wuerfels an der Position
     * "index" zurueck.
     *
     * @param index  Indexposition des Wuerfelwurfs im Wuerfelarray
     * @return pips  die aktuell gewuerfelte Zahl zwischen 1 und 6.
     */
    public int getPips (int index) 
    {
        if (this.pips.length > index) {
            return this.pips[index];
        } else {
            return 0;
        }
    }
    
    
    /**
     * Erzeuge fuer jeden sichtbaren View eine Zufallszahl zwischen 1 und 6 und 
     * uebergibt diese an die Klassenvariable pips.
     *
     * @return Das Array mit den gewuerfelten Augenzahlen.
     */
    public int[] dice () 
    {
        ArrayList visibleViews = new ArrayList();
        
        // Alle sichtbaren Views ermitteln
        int index = 0;
        Iterator iter = views.iterator();
        while (iter.hasNext()) {
            DiceView dv = (DiceView) iter.next();
            if (dv.isShowing()) {
                visibleViews.add(dv);
                index = index + 1;
            }
        }
        
        // Wuerfelwurf fuer sichtbare Views simulieren
        this.pips = new int[index];
        int[] temp = new int[index];
        for (int i = 0; i < index; i++) {
            temp[i] = (int) Math.floor(Math.random() * 6) + 1;
        }
        
        // Array sortieren (aufsteigend)
        Arrays.sort(temp);
        
        // Sortierrichtung umdrehen
        for(int i = 0; i < index; i++) {
            this.pips[i] = temp[index - 1 - i];
        }

        
        // Views aktualisieren
        iter = visibleViews.iterator();
        index = 0;
        while (iter.hasNext()) {
            ((DiceView) iter.next()).update(index);
            index = index + 1;
        }
        
        return this.pips;
    }
}
